<template>
	<view class="e-col" ref="e-col" :class="[
			'e-col-' + span
		]" :style="[colStyle]" @tap="clickHandler">
		<slot></slot>
	</view>
</template>
<script lang="ts">
	import { defineComponent } from 'vue'
	import mpMixin from "../../libs/mixin/mpMixin";
	/**
	 * CodeInput 栅格系统的列 
	 * @description 该组件一般用于Layout 布局 通过基础的 12 分栏，迅速简便地创建布局
	 * @tutorial https://www.uviewui.com/components/Layout.html
	 * @property {String | Number}	span		栅格占据的列数，总12等份 (默认 12 ) 
	 * @property {String | Number}	offset		分栏左边偏移，计算方式与span相同 (默认 0 ) 
	 * @property {String}			justify		水平排列方式，可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)  (默认 'start' ) 
	 * @property {String}			align		垂直对齐方式，可选值为top、center、bottom、stretch (默认 'stretch' ) 
	 * @property {String}			textAlign	文字水平对齐方式 (默认 'left' ) 
	 * @property {Object}			customStyle	定义需要用到的外部样式
	 * @event {Function}	click	col被点击，会阻止事件冒泡到row
	 * @example	 <e-col  span="3" offset="3" > <view class="demo-layout bg-purple"></view> </e-col>
	*/
	export default defineComponent({
		name: "e-col",
		mixins: [mpMixin],
	});
</script>

<script setup lang="ts">
	import {
		computed,
		toRefs,
		onMounted,
		inject
	} from 'vue'
	import {
		useDefaultProps
	} from '../../libs/hooks'
	import {
		colProps,
		colEmits
	} from './props';
	import {
		getPx,
		addStyle,
		addUnit,
		throwError,
	} from "../../libs/utils/_utils";
	import {
		deepMerge
	} from "../../libs/utils";
	import {
		rowContextKey
	} from '../../libs/tokens'
	import type {
		StyleProperties
	} from '../../libs/tokens'
	import componentsProps, {
		type DefaultProps
	} from "../../libs/config/componentsProps";


	const {
		col: colDefaultProps
	} = toRefs(componentsProps);

	const _props = defineProps(colProps)

	const props = useDefaultProps<DefaultProps['col']>(_props, colDefaultProps);
	const emit = defineEmits(colEmits)

	const rowContext = inject(rowContextKey)
	if (!rowContext) throwError('ECol', 'e-col需要结合e-row组件使用')


	const gridNum = 12

	const eJustify = computed(() => {
		if (props.value.justify == 'end' || props.value.justify == 'start') return 'flex-' + props.value.justify
		else if (props.value.justify == 'around' || props.value.justify == 'between') return 'space-' + props.value.justify
		else return props.value.justify
	})
	const eAlignItem = computed(() => {
		if (props.value.align == 'top') return 'flex-start'
		if (props.value.align == 'bottom') return 'flex-end'
		else return props.value.align
	})

	const colStyle = computed(() => {
		let marginLeft = 100 / 12 * Number(props.value.offset) + '%'
		// #ifdef APP-NVUE
		marginLeft = addUnit(Math.floor(rowContext.width / gridNum * Number(props.value.offset)))
		// #endif
		const style : StyleProperties = {
			// 这里写成"padding: 0 10px"的形式是因为nvue的需要
			paddingLeft: addUnit(Number(getPx(rowContext.props.gutter || '')) / 2),
			paddingRight: addUnit(Number(getPx(rowContext.props.gutter || '')) / 2),
			alignItems: eAlignItem.value,
			justifyContent: eJustify.value,
			textAlign: props.value.textAlign,
			marginLeft,
			// #ifndef APP-NVUE
			// 在非nvue上，使用百分比形式
			flex: `0 0 ${100 / gridNum * Number(props.value.span)}%`,
			// #endif
			// #ifdef APP-NVUE
			// 在nvue上，由于无法使用百分比单位，这里需要获取父组件的宽度，再计算得出该有对应的百分比尺寸
			width: addUnit(Math.floor(rowContext.width / gridNum * Number(props.value.span)))
			// #endif
		}

		return deepMerge(style, addStyle(props.value.customStyle as string))
	})

	const init = async () => {
		rowContext.getComponentWidth()
	}
	const clickHandler = () => {
		emit('click');
	}

	onMounted(() => {
		init()
	})
</script>

<style lang="scss" scoped>
@import "../../libs/theme/col.scss";
</style>